package applet.Forms;

import java.awt.event.KeyEvent;
import javax.swing.UIManager;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;

import org.apache.log4j.*;

import library.Choosers.*;
import library.JpegNodes.*;
import library.Logs.*;
import library.RemoteControl.*;
import library.Thread.*;
import library.Configuration.*;
import library.Constants.*;
import library.Forms.*;
import applet.Arguments.*;

/**
 * This frame is the body of the applet
 * 
 * The whole project has been designed to offer the choice :
 *  - to implement an applet that manages the GUI capabilities
 *  - to implement an application that manages the GUI capabilities
 *  - to implement an application without GUI capabilities
 * 
 * The processing is the same for all modes (SimpleExif library)
 * 
 * The Interface_Form interface defines the interface to respect to implement
 * the graphical frame (whether application or applet)
 * 
 * @author  JNC
 */
@SuppressWarnings("serial")
public  class JApplet_Form extends javax.swing.JApplet implements FormInterface {

    /**
     * Proposed default directory, that contains the jpeg pictures
     * Will be found reading the configuration file, but can not be assigned 
     * here as the name of the config file is not known yet
     * This constant will be assigned in the constructor
     */
    private String _DEFAULT_DIRECTORY = null;
    /**
     * Maximum delay to wait for the thread to terminate
     */
    private static final int _ENDLOOP_WAIT = 500 ; // ms
    /**
     * Maximum nbr of loops to wait for the thread to terminate
     */
    private static final int _WATCHDOG_LIMIT = 40 ;
    // loop --> max delay time = _ENDLOOP_WAIT * _WATCHDOG_LIMIT
    /**
     * The log4j log
     */
    private final Logger _logger = Logger.getLogger(JApplet_Form.class);
    /**
     * Reference to the remote control
     * If the processing part of the application needs to interact with the GUI,
     * all requests must be adressed through the remote control
     */
    private FrameRemoteControl _remoteControl;
    
    /**
     * Constructor
     */
    public JApplet_Form() throws UnknownClassException {
        // Sets the remote control attribute and registers into it
        // -------------------------------------------------------
        _logger.debug("Registering the remote control");
        setRemoteControl(new FrameRemoteControl());
    }
    
    /**
     * Initialization method that will be called after the applet is loaded
     * into the browser.
     * 
     * The init() method is called exactly once in an applet's life, when the 
     * applet is first loaded. It's normally used to read PARAM tags, start 
     * downloading any other images or media files you need, and set up the user 
     * interface. Most applets have init() methods.
     */
    public void init() {
        _logger.debug("Current directory = " + System.getProperty("user.dir"));
        
        // Finds the config filename
        // -------------------------
        AppletArguments.findConfigFilename(this);
        
        // Assigns the _DEFAULT_DIRECTORY constant
        // ---------------------------------------
        _DEFAULT_DIRECTORY = Configuration.getPathProperty(Constants._DEFAULTDIRECTORY_KEYWORD);
        
        // Runs the applet
        // ---------------
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    // change to Windows Look And Feel
                    changeToWindowsLookAndFeel();
        
                    // initialize the components
                    initComponents();
                    
                    // set the text area for the logging capability
                    // and the remote control to enable / disable the auto scroll down down capability
                    _logger.debug("Calling set parameters");
                    TextAreaAppender.setParameters(jLogTextArea, _remoteControl);
                            
                    // initializes labels
                    initializeLabels();
                    
                    // ask the focus to be set on the GO/CANCEL button
                    // must be called after the coponent has been displayed on the screen
                    // may be a good idea to call it as the last action afer the windows is
                    // display and before he control is turned over to the user
                    jGoCancelButton.requestFocusInWindow();
                }
            });
        } catch (Exception exception) {
            _logger.error("Exception caught (" + exception + ")");
            exception.printStackTrace();
        }
    }

    /**
     * The stop() method is called at least once in an applet's life, when the 
     * browser leaves the page in which the applet is embedded. The applet's 
     * start() method will be called if at some later point the browser returns 
     * to the page containing the applet. In some cases the stop() method may be 
     * called multiple times in an applet's life. Many applets you write will 
     * not have explicit stop()methods and will merely inherit one from their 
     * superclass. Your applet should use the stop() method to pause any running 
     * threads. When your applet is stopped, it should not use any CPU cycles.
     */
    public void stop() {

        int watchDog ;

        watchDog = 0;
        
        _logger.debug("stop");
        
        // request the processing thread to stop
        // -------------------------------------
        if (_remoteControl != null) {
            _remoteControl.requestProcessingThreadToStop();
        }
        
        // wait till the end of the processing with a watch dog
        // ----------------------------------------------------
        while ((_remoteControl.isProcessingThreadAlive()) && (watchDog < _WATCHDOG_LIMIT)) {
            try {
                _logger.debug("Will sleep " + _ENDLOOP_WAIT + " ms");
                Thread.sleep(_ENDLOOP_WAIT);
            }
            catch (InterruptedException exception) {
                _logger.error("InterruptedException caught while waiting : " + exception);
            }   
            
            watchDog = watchDog + 1;
        } // while
        
        if (_remoteControl.isProcessingThreadAlive()) {
            _logger.warn("The thread is still running, and will be killed");
        } else {
            _logger.debug("The thread has ended : " + watchDog + " loops required");
        }
    }
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("deprecation")
	private void initComponents() {

        jChooseActionButtonGroup = new javax.swing.ButtonGroup();
        jPanel1 = new javax.swing.JPanel();
        jGoCancelButton = new javax.swing.JButton();
        jChooseDirectoryLabel = new javax.swing.JLabel();
        jChooseDirectoryButton = new javax.swing.JButton();
        jDirectoryPathTextField = new javax.swing.JTextField();
        jSeparator1 = new javax.swing.JSeparator();
        jSeparator2 = new javax.swing.JSeparator();
        jChooseActionLabel = new javax.swing.JLabel();
        jRenameNewJpegFilesRadioButton = new javax.swing.JRadioButton();
        jCheckJpegFilesRadioButton = new javax.swing.JRadioButton();
        jRecursiveCheckBox = new javax.swing.JCheckBox();
        jShowPicturesCheckBox = new javax.swing.JCheckBox();
        jShowPicturesLabel = new javax.swing.JLabel();
        jGoLabel = new javax.swing.JLabel();
        jShowLabelsCheckBox = new javax.swing.JCheckBox();
        jFileNameBeforeLabel = new javax.swing.JLabel();
        jDigitalizationDateLabel = new javax.swing.JLabel();
        jTitleLabel = new javax.swing.JLabel();
        jFileNameAfterLabel = new javax.swing.JLabel();
        jLogScrollPane = new javax.swing.JScrollPane();
        jLogTextArea = new javax.swing.JTextArea();
        jProgressBar = new javax.swing.JProgressBar();
        jDigitalizationDateLabel3 = new javax.swing.JLabel();

        jGoCancelButton.setText("_");
        jGoCancelButton.setNextFocusableComponent(jChooseDirectoryButton);
        jGoCancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jGoCancelButtonActionPerformed(evt);
            }
        });

        jChooseDirectoryLabel.setText("1.Choose Directory");

        jChooseDirectoryButton.setText("Select directory");
        jChooseDirectoryButton.setNextFocusableComponent(jDirectoryPathTextField);
        jChooseDirectoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jChooseDirectoryButtonActionPerformed(evt);
            }
        });

        jDirectoryPathTextField.setText("Not assigned");
        jDirectoryPathTextField.setNextFocusableComponent(jGoCancelButton);
        jDirectoryPathTextField.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jDirectoryPathTextFieldFocusGained(evt);
            }
        });
        jDirectoryPathTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                jDirectoryPathTextFieldKeyTyped(evt);
            }
        });

        jChooseActionLabel.setText("2. Choose action");

        jChooseActionButtonGroup.add(jRenameNewJpegFilesRadioButton);
        jRenameNewJpegFilesRadioButton.setSelected(true);
        jRenameNewJpegFilesRadioButton.setText("Rename new Jpeg files");

        jChooseActionButtonGroup.add(jCheckJpegFilesRadioButton);
        jCheckJpegFilesRadioButton.setText("Check Jpeg files");
        jCheckJpegFilesRadioButton.setEnabled(false);

        jRecursiveCheckBox.setText("Recursive ?");

        jShowPicturesCheckBox.setSelected(true);
        jShowPicturesCheckBox.setText("Show thumbnails");
        jShowPicturesCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jShowPicturesCheckBoxActionPerformed(evt);
            }
        });

        jShowPicturesLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jShowPicturesLabel.setText("Not assigned");

        jGoLabel.setText("3. Go !");

        jShowLabelsCheckBox.setSelected(true);
        jShowLabelsCheckBox.setText("Show details");
        jShowLabelsCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jShowLabelsCheckBoxActionPerformed(evt);
            }
        });

        jFileNameBeforeLabel.setText("Not assigned");

        jDigitalizationDateLabel.setText("Not assigned");

        jTitleLabel.setText("Not assigned");

        jFileNameAfterLabel.setText("Not assigned");

        jLogScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jLogScrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        jLogScrollPane.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseMoved(java.awt.event.MouseEvent evt) {
                jLogScrollPaneMouseMoved(evt);
            }
        });

        jLogTextArea.setColumns(20);
        jLogTextArea.setEditable(false);
        jLogTextArea.setFont(new java.awt.Font("Monospaced", 0, 10)); // NOI18N
        jLogTextArea.setLineWrap(true);
        jLogTextArea.setRows(5);
        jLogScrollPane.setViewportView(jLogTextArea);

        jDigitalizationDateLabel3.setText("Not assigned");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jChooseDirectoryLabel, javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addComponent(jChooseDirectoryButton)
                        .addGap(54, 54, 54)
                        .addComponent(jDirectoryPathTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 589, Short.MAX_VALUE))
                    .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 774, Short.MAX_VALUE)
                    .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 774, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel1Layout.createSequentialGroup()
                        .addComponent(jChooseActionLabel)
                        .addGap(105, 105, 105)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jRenameNewJpegFilesRadioButton)
                            .addComponent(jCheckJpegFilesRadioButton)
                            .addComponent(jRecursiveCheckBox))
                        .addGap(42, 42, 42))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGap(23, 23, 23)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jGoCancelButton, javax.swing.GroupLayout.PREFERRED_SIZE, 107, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jShowPicturesCheckBox)
                                    .addComponent(jShowPicturesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)))
                            .addComponent(jGoLabel))
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGap(56, 56, 56)
                                .addComponent(jShowLabelsCheckBox)
                                .addGap(28, 28, 28)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jFileNameBeforeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addGap(0, 0, 0)
                                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                            .addComponent(jTitleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addGroup(jPanel1Layout.createSequentialGroup()
                                                .addComponent(jDigitalizationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addGap(18, 18, 18)
                                                .addComponent(jFileNameAfterLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE))))))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLogScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE)
                                    .addComponent(jProgressBar, javax.swing.GroupLayout.DEFAULT_SIZE, 638, Short.MAX_VALUE))))))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jChooseDirectoryLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jChooseDirectoryButton)
                    .addComponent(jDirectoryPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jChooseActionLabel)
                    .addComponent(jRenameNewJpegFilesRadioButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jCheckJpegFilesRadioButton)
                .addGap(11, 11, 11)
                .addComponent(jRecursiveCheckBox)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jGoLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jGoCancelButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jShowPicturesCheckBox))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jShowLabelsCheckBox)
                            .addComponent(jFileNameBeforeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jDigitalizationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jFileNameAfterLabel))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jTitleLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addGap(16, 16, 16)
                .addComponent(jProgressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(16, 16, 16)
                        .addComponent(jShowPicturesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(53, 53, 53))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(30, 30, 30)
                        .addComponent(jLogScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 128, Short.MAX_VALUE)
                        .addContainerGap())))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 794, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 0, Short.MAX_VALUE)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 438, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 0, Short.MAX_VALUE)))
        );
    }// </editor-fold>//GEN-END:initComponents

private void jChooseDirectoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jChooseDirectoryButtonActionPerformed
    // Event when the user clicks on the "Choose Directory" button.
    // The action is to open the JpegDirectory Chooser.
    
    DirectoryChooser chooser = new DirectoryChooser(jDirectoryPathTextField.getText());    
    
    _logger.debug("Will start directory chooser");
    String directoryPath = chooser.showOpenDialogAndReturnDirectoryPath(this);
    
    if (directoryPath == null) {
        // no selected directory
        _logger.warn("The user selected no directory");
    } else {
        _logger.info("The selected directory is " + directoryPath);
        
        // set the text in the label
        jDirectoryPathTextField.setText(directoryPath);
    }
    
    // warn the user
    _logger.info("Nothing will be processed until you press the Go! button");
}//GEN-LAST:event_jChooseDirectoryButtonActionPerformed

private void jGoCancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jGoCancelButtonActionPerformed
    // Event when the user clicks on the GO/CANCEL button
    // The action depends on the context (GO or CANCEL state)
    
    performGoCancelButtonAction();
}//GEN-LAST:event_jGoCancelButtonActionPerformed


private void jShowPicturesCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jShowPicturesCheckBoxActionPerformed
    // Event when the user clicks on the "Show Pictures" check box
    // The action is to show/hide the picture of the file being processed
    
    if (!jShowPicturesCheckBox.isSelected()) {
        jShowPicturesLabel.setIcon(null);
    }
}//GEN-LAST:event_jShowPicturesCheckBoxActionPerformed

private void jShowLabelsCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jShowLabelsCheckBoxActionPerformed
    // Event when the user clicks on the "Show Lables" check box
    // The action is to show / hide the labels of the file being processed
    
    if (!jShowLabelsCheckBox.isSelected()) {
        reinitLabels();
    }
}//GEN-LAST:event_jShowLabelsCheckBoxActionPerformed

private void jDirectoryPathTextFieldFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_jDirectoryPathTextFieldFocusGained
    // Event when the users pressed tab and gives the focus to the "Directory path" text fiels
    // knowing that a mouse click gives the focus to the TextField 
    // The action is to select the current directory path
   
    // Selects the text in the field
    jDirectoryPathTextField.selectAll();
}//GEN-LAST:event_jDirectoryPathTextFieldFocusGained

private void jDirectoryPathTextFieldKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jDirectoryPathTextFieldKeyTyped
    // Event when the user type a key in the "Directory path" text field
    // The action is to detect if this key is <Enter> and then starts to process
    // the jpeg files of this directory
    // Typing <Enter> or clicking the GO button is then the same action
    
    if (evt.getKeyChar()== KeyEvent.VK_ENTER) {
        _logger.debug("Directory path entered");
        performGoCancelButtonAction();
    }
}//GEN-LAST:event_jDirectoryPathTextFieldKeyTyped

private void jLogScrollPaneMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jLogScrollPaneMouseMoved
    // Event when the user crosses the log "Scroll pane" with the mouse
    // The action is to disable for a while the auto scroll down capability
    // of the scroll pane
    _logger.debug("JApplet_Form::jLogScrollPaneMouseMoved");
    _remoteControl.disableAutoScrollDownTemporary();   
}//GEN-LAST:event_jLogScrollPaneMouseMoved


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JRadioButton jCheckJpegFilesRadioButton;
    private javax.swing.ButtonGroup jChooseActionButtonGroup;
    private javax.swing.JLabel jChooseActionLabel;
    private javax.swing.JButton jChooseDirectoryButton;
    private javax.swing.JLabel jChooseDirectoryLabel;
    private javax.swing.JLabel jDigitalizationDateLabel;
    private javax.swing.JLabel jDigitalizationDateLabel3;
    private javax.swing.JTextField jDirectoryPathTextField;
    private javax.swing.JLabel jFileNameAfterLabel;
    private javax.swing.JLabel jFileNameBeforeLabel;
    private javax.swing.JButton jGoCancelButton;
    private javax.swing.JLabel jGoLabel;
    private javax.swing.JScrollPane jLogScrollPane;
    private javax.swing.JTextArea jLogTextArea;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JProgressBar jProgressBar;
    private javax.swing.JCheckBox jRecursiveCheckBox;
    private javax.swing.JRadioButton jRenameNewJpegFilesRadioButton;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JCheckBox jShowLabelsCheckBox;
    private javax.swing.JCheckBox jShowPicturesCheckBox;
    private javax.swing.JLabel jShowPicturesLabel;
    private javax.swing.JLabel jTitleLabel;
    // End of variables declaration//GEN-END:variables

    /**
     * Performs all necessary action when the GO/CANCEL button is pressed
     */
    private void performGoCancelButtonAction() {
         ActionTypeEnum action;
    
        // determines the state of the GO button
        if (jGoCancelButton.getText().equals(_LABEL_GO)) {
            // pressing the button means GO
            // ----------------------------
            _logger.debug("The user pressed the Go! button");    
        
            // changes the label of the button
            jGoCancelButton.setText(_LABEL_CANCEL);
        
            // determines the requested action
            action = selectedAction();
    
            if (action == ActionTypeEnum.None) {
                _logger.warn("No action selected !");
            } else {
                // starts the thread
                try {
                    new ProcessingThread(jDirectoryPathTextField.getText(),
                                        action,
                                        jRecursiveCheckBox.isSelected(),
                                        _remoteControl).start();
                }
                catch(UnknownClassException exception) {
                    _logger.error("Exception Exception_UnknownClassException caught while creating Class_processingThread : " + exception);
                }
            }
        } else {
            // pressing the button means CANCEL
            // --------------------------------
            _logger.debug("The user pressed the Cancel! button");
            
            // request the thread to stop
            _remoteControl.requestProcessingThreadToStop();
            
            // It is not time yet to set the text of the GO/CANCEL button to GO
            // The text will be reinitialized only when the processing thread will stop
            // It is time however to desactivate the GO/CANCEL button
            // The button will be reactivated when the processing thread will stop
            _remoteControl.activateGoCancelButton(false);
        }       
    }
    
    /**
     * Initializes all labels
     */
    private void initializeLabels() {
        
        // sets the label to default directory
        jDirectoryPathTextField.setText(_DEFAULT_DIRECTORY);
        _logger.info("The default directory is " + _DEFAULT_DIRECTORY);
        
        // void the text label designed to show the thumbnails (assigned to any value be visible in the frame editor)
        jShowPicturesLabel.setText(null);
        
        // void the text for the other labels (assigned to any value be visible in the frame editor)        
        reinitLabels();
        
        // set the GO label on the GO button
        jGoCancelButton.setText(_LABEL_GO);               
}
          
    /**
     * Indicates the action requested by the user (check boxes).
     * @return
     * the action requested by the user.
     */
    private ActionTypeEnum selectedAction() {
        ActionTypeEnum ret;
        
        if (jRenameNewJpegFilesRadioButton.isSelected()) {
            _logger.info("Rename new Jpeg files !");
            ret = ActionTypeEnum.Rename;
        } else {
            if (jCheckJpegFilesRadioButton.isSelected()) {
                _logger.info("Check Jpeg file names !");
                ret = ActionTypeEnum.Check;
            } else {
                _logger.info("No action selected !");
                ret=ActionTypeEnum.None;
            }
        }
    return ret;
    }
    
    /**
     * Disables all the commands of the frame during the processing to avoid the user to start a new action
     * As a public method requesting form update, it must be called exclusively through a remote control
     * (the remote control will ensure this method is executed in the EDT thread)     */
    public void enableCommands(boolean myIsEnabled) {
        enableChooseDirectoryButton(myIsEnabled);
        enableDirectoryPathTextField(myIsEnabled);
        enableRenameNewJpegFilesRadioButton(myIsEnabled);
        enableRecursiveCheckBox(myIsEnabled);
    }
    
    /**
     * gets jShowPicturesLabel.
     * @return the label that encloses the thumbnail.
     */
    public javax.swing.JLabel getShowPicturesLabel() {
        return jShowPicturesLabel;
    }
    
    /**
     * set the text in jFileNameBeforeLabel
     * @param myText
     */
    public void setFileNameBeforeLabelText(String myText) {
        jFileNameBeforeLabel.setText(myText);
    }
    
    /**
     * set the text in jFileNameAfterLabel
     * @param myText
     */
    public void setFileNameAfterLabelText(String myText) {
        jFileNameAfterLabel.setText(myText);
    }
    
    /**
     * set the text in jTitleLabel
     * @param myText
     */
    public void setTitleLabelText(String myText) {
        jTitleLabel.setText(myText);
    }
    
    /**
     * set the text in jDigitalizationDateLabel
     * @param myText
     */
    public void setDigitalizationDateLabelText(String myText) {
        jDigitalizationDateLabel.setText(myText);
    }

    /**
     * allow to enable/disable jChooseDirectoryButton
     * @param myIsEnabled
     */
    private void enableChooseDirectoryButton (boolean myIsEnabled) {
        jChooseDirectoryButton.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jDirectoryPathTextField
     * @param myIsEnabled
     */
    private void enableDirectoryPathTextField(boolean myIsEnabled) {
        jDirectoryPathTextField.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jRenameNewJpegFilesRadioButton
     * @param myIsEnabled
     */
    private void enableRenameNewJpegFilesRadioButton(boolean myIsEnabled) {
        jRenameNewJpegFilesRadioButton.setEnabled(myIsEnabled);
    }
    
    /**
     * allow to enable/disable jRecursiveCheckBox
     * @param myIsEnabled
     */
    private void enableRecursiveCheckBox(boolean myIsEnabled) {
        jRecursiveCheckBox.setEnabled(myIsEnabled);
    }
    
    /**
     * indicates if jShowPicturesCheckBox is checked
     * @return status of the checkbox that indicates if the thumbnail of the file
     * that is being processed must be shown
     */
    public boolean isShowPicturesCheckBoxSelected() {
        return jShowPicturesCheckBox.isSelected();
    }
    
    /**
     * indicates if jShowLabelsCheckBox is checked
     * @return status of the checkbox that indicates if the details of the file 
     * that is being processed must be shown
     */
    public boolean isShowLabelsCheckBoxSelected() {
        return jShowLabelsCheckBox.isSelected();
    }

    /**
     * set the string in the progress bar
     * @param myMsg
     */
    public void setProgressBarString(String myMsg) {
        jProgressBar.setString(myMsg);
    }
    
    /**
     * set the painting in the progress bar
     * @param myIsPainted
     */
    public void setProgressBarStringPainted(boolean myIsPainted) {
        jProgressBar.setStringPainted(myIsPainted);
    }
    
    /**
     * set the progress bar in indeterminate mode
     * @param myIsIndeterminate
     */
    public void setProgressBarIndeterminate(boolean myIsIndeterminate) {
        jProgressBar.setIndeterminate(myIsIndeterminate);
    }
    
    /**
     * set the progress value in the progress bar
     * @param myValue
     */
    public void setProgressBarValue(int myValue) {
        jProgressBar.setValue(myValue);
    }

    /**
     * Reinits the progress bar
     */
    public void reinitProgressBar() {
        jProgressBar.setStringPainted(false);
        jProgressBar.setValue(0);
    }
    
    /**
     * set the image icon in jShowPictureLabel
     * @param myImageIcon
     */
    public void setShowPicturesLabelIcon(ImageIcon myImageIcon) {
        jShowPicturesLabel.setIcon(myImageIcon);
    }

    /**
     * get the width of the jShowPicturesLabel
     * @return width of the label that encloses the thumbnail.
     */
    public int getShowPicturesLabelWidth() {
        return jShowPicturesLabel.getWidth();
    }

    /**
     * get the height of the jShowPicturesLabel
     * @return height of the label that encloses the thumbnail.
     */
    public int getShowPicturesLabelHeight() {
        return jShowPicturesLabel.getHeight();
    }
    
    /**
     * Change the frame to the Windows Look & Feel
     */
    private void changeToWindowsLookAndFeel() {
        
        // change the look and feel to Windows Classic Look and Feel
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
            SwingUtilities.updateComponentTreeUI(this);
        }
        catch (InstantiationException exception) {
            _logger.debug("Exception InstantiationException caught : " + exception);
        }
        catch (ClassNotFoundException exception) {
            _logger.debug("Exception ClassNotFoundException caught : " + exception);
        }
        catch (UnsupportedLookAndFeelException exception) {
            _logger.debug("Exception UnsupportedLookAndFeelException caught : " + exception);
        }
        catch (IllegalAccessException exception) {
            _logger.debug("Exception IllegalAccessException caught : " + exception);
        }        
    }
  
    /**
     * Set the text of the GO/CANCEL button
     * @param myString The text to set to the button
     */
    public void reinitGoCancelButton() {
        jGoCancelButton.setText(_LABEL_GO);
    }
    
    /**
     * Activates or desactivates the GO/CANCEL button
     * As a public method requesting form update, it must be called exclusively through a remote control
     * (the remote control will ensure this method is executed in the EDT thread)
     * @param myActivation indicates if the button must be activated (true) or desactivated (false)
     */
    public void activateGoCancelButton(boolean myActivation) {
        jGoCancelButton.setEnabled(myActivation);
    }
    
    /**
     * reinitialize the labels describing the file before/after renaming
     */
    public void reinitLabels() {
        jFileNameBeforeLabel.setText(null);
        jTitleLabel.setText(null);
        jDigitalizationDateLabel.setText(null);
        jFileNameAfterLabel.setText(null);    
    }
    
    /**
     * Sets the remote control as attribute, and registers the applet in the 
     * remote control.
     * @param myRemoteControl
     * The remote control to set as attribute
     */
    private void setRemoteControl(FrameRemoteControl myRemoteControl)
        throws UnknownClassException {
        
        _remoteControl = myRemoteControl;
        _remoteControl.register(this);
    }
    
    /**
     * Changes the shape of the border of the text area depending whether the scroll down is enabled or disabled
     * As a public method requesting form update, it must be called exclusively through a remote control
     * (the remote control will ensure this method is executed in the EDT thread)     * @param isTransient
     */
    public void changeBorderToTransient(boolean myIsTransient) {
        if (myIsTransient) {
            jLogScrollPane.setViewportBorder(javax.swing.BorderFactory.createMatteBorder(1, 1, 1, 1, new java.awt.Color(204, 0, 51)));
//            jLogScrollPane.getViewport().repaint();
        } else {
            jLogScrollPane.setViewportBorder(null);
        }

//        this.repaint();
        jLogScrollPane.repaint();
//        jLogTextArea.repaint();
    }
}
